<?php

	namespace org\tekuna\framework\component;

	use \Exception;

	use org\tekuna\core\application\Application;
	use org\tekuna\core\context\Context;
	use org\tekuna\core\configuration\ConfigurationElement;

	use org\tekuna\framework\RequestDispatchException;
	use org\tekuna\framework\request\Request;

	
	/**
	 * This class processes all declared components to find the matching component
	 * for the current HttpRequest. The matching is done by the base URL.
	 */
	class HttpComponentProcessor {

		private
			$objContext = NULL,
			$arrComponents = array();


		/**
		 * Construct a new HttpComponentProcessor
		 * 
		 * @param Context $objContext the application context
		 */
		public function __construct(Context $objContext) {

			$this -> objContext = $objContext;

			// TODO: some validation of the configured components
			$objParentElement = $objContext -> getConfiguration() -> getRootElement();
			$this -> arrComponents = $objParentElement -> getAllChildElements('framework', 'component');
		}


		/**
		 * Processes all declared components and returns the component that
		 * matches for the current request (base URL)
		 * 
		 * @return ConfigurationElement the component's configuration element
		 * @throws ComponentException if anything goes wrong
		 * @throws RequestDispatchException if no matching component was found
		 */
		public function getMatchingHttpComponent() {

			foreach ($this -> arrComponents as $objComponent) {

				try {

					if ($this -> isMatchingHttpComponent($objComponent)) {

						return $objComponent;
					}
				}
				catch (Exception $objException) {

					throw new ComponentException("Error while matching HTTP component ". trim($objComponent -> __toString()), -1, $objException);
				}
			}

			throw new RequestDispatchException("No matching HTTP component found.");
		}

		
		protected function isMatchingHttpComponent(ConfigurationElement $objElement) {

			// get the request action
			$sRequestAction = $this -> objContext -> getRequest() -> getRequestAction();

			// get the component's base url
			$sComponentBaseUrl = $objElement -> getAttribute('framework', 'baseUrl') -> getValue();

			// check if the action starts with the current component
			$bActionStartsWithComponentBaseUrl = (substr($sRequestAction, 0, strlen($sComponentBaseUrl)) === $sComponentBaseUrl);

			return $bActionStartsWithComponentBaseUrl;
		}
	}

